package com.encryption.rpc;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.encryption.dao.Condition;
import com.encryption.dao.FileLogDAO;
import com.encryption.dao.FilePermissionAssoDAO;
import com.encryption.logic.DocOperationHelper;
import com.encryption.logic.FileActionConstant;
import com.encryption.logic.FilePermissionService;
import com.encryption.logic.impl.FilePermissionParser;
import com.encryption.logic.impl.FilePermissionServiceImpl;
import com.encryption.model.Department;
import com.encryption.model.File;
import com.encryption.model.FileLog;
import com.encryption.model.FilePermissionAsso;
import com.encryption.model.FilePermissionConf;
import com.encryption.model.User;
import com.encryption.rpc.model.WrapperPageInfo;
import com.encryption.service.DepartmentService;
import com.encryption.service.FileService;
import com.encryption.service.UserService;
import com.encryption.service.impl.DepartmentServiceImpl;
import com.encryption.service.impl.FileServiceImpl;
import com.encryption.service.impl.UserServiceImpl;
import com.encryption.service.qrc.DocProcessParam;
import com.log4ic.DocViewer;
import com.log4ic.utils.io.FileEncryption;
import com.log4ic.utils.io.FileUtils;

import flex.messaging.util.UUIDUtils;

public class FileFacade {
	private static FileService fileService = FileServiceImpl.getFileServiceImpl();
	private static FilePermissionService filePermissionService = FilePermissionServiceImpl
			.getFilePermissionServiceImpl();
	private static FilePermissionAssoDAO filePermissionAssoService = FilePermissionAssoDAO
			.getFilePermissionAssoDAO();
	private static UserService userService = UserServiceImpl.getUserServiceImpl();
	private static DepartmentService departService = DepartmentServiceImpl
			.getDepartmentServiceImpl();
	
	private static Object synObj = new Object();

	public boolean upload(final com.encryption.model.File file, byte[] bytes,
			final FilePermissionConf conf) {
		String fileName = UUIDUtils.createUUID();
		String suffix = FileUtils.getFileSuffix(file.getName());

		fileName = fileName + "." + suffix;
		FileUtils.writeFile(fileName, bytes);
		file.setFileUrl("/file/" + fileName);
		file.setUploadTime(new Date());
		file.setSize(bytes.length);

		fileService.addFile(file);
//		DocOperationHelper.addWaterMark(conf, file);

		if (!"word".equalsIgnoreCase(file.getType())) {
			String targetFile = DocOperationHelper.converter(fileName);

			int index = targetFile.lastIndexOf("/");
			String targetFileName = targetFile.substring(index + 1);

			file.setSwfUrl("/file/target/" + targetFileName);
			file.setEncryptionUrl(file.getSwfUrl() + ".sec");

			fileService.updateFile(file);

			DocOperationHelper.encryptFile(conf, file, true);
			
		}

		List<FilePermissionAsso> assoList = FilePermissionParser.parse(file,
				conf);
		for (FilePermissionAsso asso : assoList) {
			filePermissionService.add(asso);
		}
		
		final String deleteFileName = fileName;
		final File upLoadFile = file;
		new Thread(){
			public void run() {
				if(!"word".equalsIgnoreCase(upLoadFile.getType())){
					DocOperationHelper.deleteTempFile(deleteFileName, DocViewer.getInputPath());
				}else{
					String encryFile = DocViewer.getInputPath() + "/" + deleteFileName;
					try {
						FileEncryption.encrypt(encryFile, encryFile + ".sss");
						FileUtils.deleteFile(encryFile, false);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}.start();

		return true;
	}

	public void deleteDoc(String fileName) {
		String filePath = FilePermissionParser.FILE_PATH + "/file/temp/"
				+ fileName;
		DocOperationHelper.deleteDoc(filePath);
	}
	
	public void deleteWordSwfFile(String fileName){
		String swfFileName = "";
		if(fileName.indexOf(".doc") != -1)
			swfFileName = FilePermissionParser.FILE_PATH + "/file/temp/target/" + fileName;
		else
			swfFileName = FilePermissionParser.FILE_PATH + "/file/target/" + fileName;
		DocOperationHelper.deleteFile(swfFileName);
	}
	
	public void decrytionFile(String fileName){
		String swfFileName = FilePermissionParser.FILE_PATH + "/file/target/" + fileName;
		String encrytionFile = swfFileName + ".sss";
		try {
			FileEncryption.decrypt(encrytionFile, swfFileName);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public String viewDoc(User user, File file) throws Exception{
		return addWaterMark(user, file, FileActionConstant.ACTION_VIEW);
	}

	public String addWaterMark(User user, File file, int fileAction) throws Exception {
		synchronized (synObj) {
			
			DocProcessParam param = FilePermissionParser.parse(user, file);
			FileEncryption.decrypt(param.getSourceFilePath() + ".sss", param.getTargetFilePath());
//			DocOperationHelper.coryDoc(param);
			param.setSourceFilePath(param.getTargetFilePath());
			
			FileLog fileLog = new FileLog();
			fileLog.setFile(file.getId());
			fileLog.setFileAction(fileAction);
			fileLog.setTime(new Date());
			fileLog.setUser(user.getId());
			FileLogDAO.getFileLogDAO().save(fileLog);
			if(fileLog.getId().intValue() == 0)
				throw new Exception("读取文件失败");
			
			param.setLogId(fileLog.getId());
			
			DocOperationHelper.addWaterMark(param);
			String targetPath = param.getTargetFilePath();
			String fileName = targetPath.substring(targetPath.lastIndexOf("/") + 1);
			String targetName = DocOperationHelper.converter(fileName,
					FilePermissionParser.FILE_PATH + "/file/temp",
					FilePermissionParser.FILE_PATH + "/file/temp/target");
			String targetUrl = "/file/temp/target/" + targetName;
//			FileUtils.deleteFile(param.getSourceFilePath(), false);
			
			final String deleteFileName = fileName;
			new Thread(){
				public void run() {
					String preffixName = FileUtils.getFilePrefix(deleteFileName);
					DocOperationHelper.deleteTempFile(preffixName, DocViewer.getInputPath() + "/temp");
				}
			}.start();
			return targetUrl;
		}
	}

	public String downFile(User user, File file) throws Exception {
		synchronized (synObj) {
			String swfFile = addWaterMark(user, file, FileActionConstant.ACTION_DOWNLOAD);
			List<FilePermissionAsso> assoList = filePermissionService
			.getByFileId(file.getId());
			FilePermissionConf conf = FilePermissionParser.deParse(assoList);
			file.setSwfUrl(swfFile);
			String encrytionUrl = file.getSwfUrl() + ".sec";
			file.setEncryptionUrl(encrytionUrl);
			DocOperationHelper.encryptFile(conf, file);
			
			return encrytionUrl;
		}
		
	}

	public WrapperPageInfo getFilePagingByCondition(List<Condition> condList,
			User user, int page, int pageSize) {
		List<com.encryption.model.File> fileList = fileService
				.getFilePagingByCondition(condList, user, page, pageSize);

		if (fileList == null || fileList.size() == 0)
			return new WrapperPageInfo();

		List<FilePermissionAsso> assoList = filePermissionAssoService
				.getPermissionsByCondition(fileList);

		for (com.encryption.model.File file : fileList) {
			User uploadUser = userService.getUserById(file.getUser());
			Department depart = departService.getDepartmentById(file
					.getDepartment() + "");
			file.setDepartObj(depart);
			file.setUserObject(uploadUser);
			if (user.getId().equals(file.getUser())) {
				file.setCanDelete(true);
				file.setCanDownload(true);
				file.setCanView(true);
				file.setCanPrint(true);
			} else {
				file.setCanDelete(false);
				for (FilePermissionAsso asso : assoList) {
					if (file.getId().equals(asso.getFile())) {
						file.setCanDownload(asso.getAllowDownload().equals(1));
						file.setCanView(asso.getAllowView().equals(1));
						file.setCanPrint(asso.getAllowPrint().equals(1));
						break;
					}
				}
			}

			boolean has = hasOperate(file, user);
			file.setHasOperate(has);
		}

		int recordCount = getPagingCountByCondition(condList, user);
		int allPageCount = (int) Math.ceil(((double) recordCount) / pageSize);
		WrapperPageInfo wraper = new WrapperPageInfo();
		wraper.setDataList(fileList);
		wraper.setAllPageCount(allPageCount);
		wraper.setCurrentPage(page);
		wraper.setPageSize(pageSize);
		wraper.setRecordCount(recordCount);

		return wraper;
	}

	private boolean hasOperate(com.encryption.model.File file, User user) {
		List<Condition> condList = new ArrayList<Condition>();
		Condition fileIdCond = new Condition("file", Condition.EQ, file.getId());
		condList.add(fileIdCond);
		Condition userIdCond = new Condition("user", Condition.EQ, user.getId());
		condList.add(userIdCond);

		List<FileLog> logList = FileLogDAO.getFileLogDAO().findByExample(
				condList);
		return logList != null && logList.size() > 0;
	}

	public int getPagingCountByCondition(List<Condition> condList, User user) {
		return fileService.getFilePagingCountByCondition(condList, user);
	}

	public List<com.encryption.model.File> getFileByCondition(User user,
			List<Condition> condList) {
		List<com.encryption.model.File> fileList = fileService
				.getFileByCondition(condList);
		// FilePermissionSetter.setPermissionList(user, fileList);

		return fileList;
	}

	public void deleteFile(int id) {
		File file = fileService.getById(id + "");
		fileService.deleteFile(id + "");
		String fileUrl = FilePermissionParser.FILE_PATH + file.getFileUrl();
		DocOperationHelper.deleteDoc(fileUrl);
	}
}
